import base64
from Crypto.Cipher import AES
from django.contrib.auth.hashers import make_password
from rest_framework import views, response, status, filters, mixins, permissions
from rest_framework.viewsets import GenericViewSet
from rest_framework_jwt.views import JSONWebTokenAPIView
from apps.user.serializers import RegisterModelSerializer, LoginSerializer, UserModelSerializer, UserPwdModelSerializer
from apps.user.models import UserModel
from utils.response import data_response, message_response


class LoginView(JSONWebTokenAPIView):
    serializer_class = LoginSerializer

    def post(self, request, *args, **kwargs):
        """登录"""
        try:
            if request.data['key']:
                aes = AES.new(str.encode(request.data['key']), AES.MODE_ECB)
                del request.data['key']
                request.data['password'] = \
                    str(aes.decrypt(base64.decodebytes(bytes(request.data['password'], encoding='utf8')))
                        .rstrip(b'\0').decode("utf8")).replace('\n', '').replace('\b', '')
        except Exception as e:
            pass
        serializer = LoginSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            user = serializer.object.get("user")
            token = serializer.object.get("token")
            result = data_response(user=user, token=token)
            return response.Response(result, status=status.HTTP_200_OK)


class RegisterView(views.APIView):

    def post(self, request, *args, **kwargs):
        """注册"""
        try:
            if request.data['key']:
                aes = AES.new(str.encode(request.data['key']), AES.MODE_ECB)
                del request.data['key']
                request.data['password'] = \
                    str(aes.decrypt(base64.decodebytes(bytes(request.data['password'], encoding='utf8')))
                        .rstrip(b'\0').decode("utf8")).replace('\n', '').replace('\b', '')
                request.data['confirm_password'] = \
                    str(aes.decrypt(base64.decodebytes(bytes(request.data['confirm_password'], encoding='utf8')))
                        .rstrip(b'\0').decode("utf8")).replace('\n', '').replace('\b', '')
        except Exception as e:
            pass
        serializer = RegisterModelSerializer(data=request.data)
        if serializer.is_valid(raise_exception=True):
            serializer.save()
            result = data_response(data=serializer.data)
        return response.Response(result, status=status.HTTP_201_CREATED)


class UsernameIsExistedView(views.APIView):
    def get(self, request, username):
        """判断用户名是否已被注册"""
        user_id = ''
        try:
            user_id = UserModel.objects.get(username=username).id
        except Exception as e:
            pass
        if user_id != '':
            message = {"id": user_id, "username": "该账号已被注册！"}
            result = message_response(code=1, message=message)
            return response.Response(result, status=status.HTTP_200_OK)
        else:
            message = {"username": "该账号未被注册！"}
            result = message_response(code=0, message=message)
            return response.Response(result, status=status.HTTP_200_OK)


# class EmailIsExistedView(views.APIView):
#     def get(self, request, email):
#         """判断邮箱是否已被注册"""
#         user_id = ''
#         try:
#             user_id = UserModel.objects.get(email=email).id
#         except Exception as e:
#             pass
#         if user_id != '':
#             message = {"id": user_id, "email": "该邮箱已被注册！"}
#             result = message_response(code=1, message=message)
#             return response.Response(result, status=status.HTTP_200_OK)
#         else:
#             message = {"email": "该邮箱未被注册！"}
#             result = message_response(code=0, message=message)
#             return response.Response(result, status=status.HTTP_200_OK)


class UserViewSet(mixins.ListModelMixin,
                  mixins.RetrieveModelMixin,
                  GenericViewSet):
    queryset = UserModel.objects.all()
    serializer_class = UserModelSerializer
    permission_classes = [permissions.IsAuthenticated]
    filter_backends = [filters.OrderingFilter]
    ordering_fields = ['create_time']

    def retrieve(self, request, *args, **kwargs):
        instance = self.get_object()
        serializer = self.get_serializer(instance)
        result = data_response(data=serializer.data)
        return response.Response(result, status=status.HTTP_200_OK)

    def list(self, request, *args, **kwargs):
        keyword = request.query_params.get("username")
        if keyword != '':
            qs = self.get_queryset().filter(username__icontains=keyword).order_by("-create_time")
        else:
            qs = self.get_queryset().order_by("-create_time")

        page = self.paginate_queryset(qs)
        if page is not None:
            serializer = self.get_serializer(page, many=True)
            page_data = self.get_paginated_response(serializer.data)
            for result in page_data.data["results"]:
                result["is_superuser"] = "管理员" if result["is_superuser"] == 1 else "普通用户"
            result = data_response(data=page_data.data)
            return response.Response(result, status=status.HTTP_200_OK)

        serializer = self.get_serializer(qs, many=True)
        result = data_response(data=serializer.data)
        return response.Response(result, status=status.HTTP_200_OK)

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        result = data_response(data=serializer.data)
        return response.Response(result, status=status.HTTP_200_OK)

    def perform_update(self, serializer):
        serializer.save()

    def partial_update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)


class UserPwdViewSet(mixins.UpdateModelMixin, GenericViewSet):
    queryset = UserModel.objects.all()
    serializer_class = UserPwdModelSerializer
    permission_classes = [permissions.IsAuthenticated]

    def update(self, request, *args, **kwargs):
        partial = kwargs.pop('partial', False)
        instance = self.get_object()
        try:
            if request.data['key']:
                aes = AES.new(str.encode(request.data['key']), AES.MODE_ECB)
                del request.data['key']
                request.data['old_password'] = \
                    str(aes.decrypt(base64.decodebytes(bytes(request.data['old_password'], encoding='utf8')))
                        .rstrip(b'\0').decode("utf8")).replace('\n', '').replace('\b', '')
                request.data['new_password'] = \
                    str(aes.decrypt(base64.decodebytes(bytes(request.data['new_password'], encoding='utf8')))
                        .rstrip(b'\0').decode("utf8")).replace('\n', '').replace('\b', '')
        except Exception as e:
            pass
        request.data["password"] = make_password(request.data["new_password"])
        serializer = self.get_serializer(instance, data=request.data, partial=partial)
        serializer.is_valid(raise_exception=True)
        self.perform_update(serializer)

        if getattr(instance, '_prefetched_objects_cache', None):
            instance._prefetched_objects_cache = {}
        result = message_response(code=0, message={"password": "密码修改成功！"})
        return response.Response(result, status=status.HTTP_200_OK)

    def perform_update(self, serializer):
        serializer.save()

    def partial_update(self, request, *args, **kwargs):
        kwargs['partial'] = True
        return self.update(request, *args, **kwargs)
